package com.basic.business.dingTalk.utils;
import com.basic.business.dingTalk.domain.TDingTalkMgmt;
import com.basic.common.constant.CacheConstants;
import com.basic.common.core.redis.RedisCacheUtils;
import com.basic.common.utils.StringUtils;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiRobotSendRequest;
import com.dingtalk.api.response.OapiRobotSendResponse;
import com.taobao.api.ApiException;
import org.apache.commons.codec.binary.Base64;
import org.springframework.util.Assert;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;

/**
 * 钉钉工具类
 */
public class DingTalkUtils {

    public static void send (String content, String orderType, Object atMobiles){
        // 获取Redis中的钉钉配置消息
        List<TDingTalkMgmt> talks = RedisCacheUtils.getCacheObject(CacheConstants.DING_TALK_REDIS_KEY);
        Assert.notNull(talks, "钉钉配置信息为空");

        talks.forEach(talk -> {
            if (StringUtils.equals(orderType, talk.getChatType())) {
                // 获取webhook
                String webhook = talk.getWebhook();
                // 获取secret
                String secret = talk.getSecret();
                // 获取时间戳
                Long timestamp = System.currentTimeMillis();
                // 获取签名
                String sign = getSign(timestamp, secret);
                // @人
                String atMobilesStr = talk.getAtMobiles();

                // 如果 atMobilesStr 为空，则直接使用传入的 atMobiles
                if (StringUtils.isEmpty(atMobilesStr)) {
                    atMobilesStr = String.valueOf(atMobiles);
                } else {
                    // 否则将 atMobiles 追加到 atMobilesStr
                    atMobilesStr = atMobilesStr + "," + atMobiles;
                }

                sendTextMessage(webhook, sign, timestamp, content, atMobilesStr);
            }
        });
    }

    /**
     * 钉钉签名
     */
    private static String getSign(Long timestamp, String secret){
        try {
            String stringToSign = timestamp + "\n" + secret;
            Mac mac = Mac.getInstance("HmacSHA256");
            mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
            byte[] signData = mac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8));
            return URLEncoder.encode(new String(Base64.encodeBase64(signData)), "UTF-8");
        }  catch (Exception e) {
            throw new RuntimeException("获取钉钉签名失败");
        }
    }

    /**
     * 发送文本消息
     */
    private static void sendTextMessage(String webhook, String sign, Long timestamp,String content, Object atMobiles){
        try {
            DingTalkClient client = new DefaultDingTalkClient(webhook + "&sign=" + sign + "&timestamp=" + timestamp);
            OapiRobotSendRequest req = new OapiRobotSendRequest();

            OapiRobotSendRequest.Text text = new OapiRobotSendRequest.Text();
            text.setContent(content);
            //定义 @ 对象
            OapiRobotSendRequest.At at = new OapiRobotSendRequest.At();
            at.setAtMobiles(Arrays.asList(String.valueOf(atMobiles).split(",")));
            req.setAt(at);
            //设置消息类型
            req.setMsgtype("text");
            req.setText(text);
            OapiRobotSendResponse rsp = client.execute(req);
            System.out.println(rsp.getBody());
        } catch (ApiException e) {
            throw new RuntimeException("钉钉发送消息失败");
        }
    }

}
